//C19: Listing 19.8 -- create vecotor and access the elemnts of vector.
#include <iostream>
#include <ostream>
#include <string>
#include <vector>
using namespace std;

class Student
{
    public:
        Student();
        Student(const string& name, const int age);
        Student(const Student& rhs);
        ~Student();

        void SetName(const string& name);
        string GetName() const;
        void SetAge(const int age);
        int GetAge() const;

        Student& operator=(const Student& rhs);
    private:
        string itsName;
        int itsAge;
};

Student::Student()
: itsName("New Student"), itsAge(16) {}

Student::Student(const string& name, const int age)
: itsName(name), itsAge(age) {}

Student::Student(const Student& rhs)
: itsName(rhs.GetName()), itsAge(rhs.GetAge()) {}
Student::~Student() {}

void Student::SetName(const string &name)
{
    itsName = name;
}

string Student::GetName() const
{
    return itsName;
}

void Student::SetAge(const int age)
{
    itsAge = age;
}

int Student::GetAge() const
{
    return itsAge;
}

Student& Student::operator=(const Student &rhs)
{
    itsName = rhs.GetName();
    itsAge = rhs.GetAge();
    return *this;
}

ostream& operator<<(ostream& os, const Student& rhs)
{
    os << rhs.GetName() << " is " << rhs.GetAge() << " years old";
    return os;
}

template<class T>
// display vector properties
void ShowVector(const vector<T>& v);

typedef vector<Student> SchoolClass;

int main(void)
{
    Student Harry;
    Student Sally("Sally", 15);
    Student Bill("Bill", 17);
    Student Peter("Peter", 16);

    SchoolClass EmptyClass;
    cout << "EmptyClass" << endl;
    ShowVector(EmptyClass);

    SchoolClass GrowingClass(3);
    cout << "GrowingClass(3):" << endl;
    ShowVector(GrowingClass);

    GrowingClass[0] = Harry;
    GrowingClass[1] = Sally;
    GrowingClass[2] = Bill;
    cout << "GrowingClass(3) after assigning students:" << endl;
    ShowVector(GrowingClass);

    GrowingClass.push_back(Peter);
    cout << "GrowingClass() after added 4th student:" << endl;
    ShowVector(GrowingClass);
}

//Display vector properties
template<class T>
void ShowVector(const vector<T>& v)
{
    cout << "max_size() = " << v.max_size();
    cout << "\tsize() = " << v.size();
    cout << "\tcapacity() = " << v.capacity();
    cout << "\t" << v.empty()? "empty" : "not empty";
    cout << endl;

    for (int i = 0; i < v.size(); i++)
    {
        cout << v[i] << endl;
    }
    cout << endl;
}